import os

from django.core.files.storage import FileSystemStorage
from rest_framework.decorators import api_view
from rest_framework.response import Response

from django.conf import settings
from .serializers import MyUserSerializer, VideoSerializer, CommentSerializer, LikeSerializer, ScoreSerializer, \
    CollectSerializer
from .models import myUser, video, comment, like, score, VideoTags, collect
from drf_spectacular.utils import extend_schema
from django.db.models import Avg, Count, Q, F, Subquery, OuterRef  # 添加这个导入
from django.db.models.functions import Round


@extend_schema(
    summary="登录",
    description="返回登录用户信息",
    responses={200: MyUserSerializer}
)
@api_view(['POST'])
def login(request):
    try:
        user = myUser.objects.get(username=request.data['username'])
        if user.password == request.data['password']:
            user = myUser.objects.annotate(
                average_score=Round(Avg('score__score'), 1),
                comment_likes=Count('comment__like__is_like', filter=Q(comment__like__is_like=True),
                                    distinct=True),
                comment_dislikes=Count('comment__like__is_dislike', filter=Q(comment__like__is_dislike=True),
                                       distinct=True),
                comment_count=Count('comment', distinct=True),
                collect_count=Count('collect', distinct=True)
            ).get(username=request.data['username'])
            serializer = MyUserSerializer(user)
            request.session['token'] = user.id
            return Response({
                'message': '登录成功',
                'data': serializer.data,
                'code': 200
            }, status=200)
        else:
            return Response({
                'message': '账号密码错误',
                'code': 400
            }, status=400)
    except Exception as e:
        print(str(e))
        return Response({
            'message': f'登录失败: {str(e)}',
            'code': 400
        }, status=400)


@extend_schema(
    summary="注册",
    description="返回注册信息",
    responses={200: MyUserSerializer}
)
@api_view(['POST'])
def register(request):
    try:
        username = request.data['username']
        password = request.data['password']
        user = myUser.objects.create(username=username, password=password)
        serializer = MyUserSerializer(user)
        return Response({
            'message': '注册成功',
            'data': serializer.data,
            'code': 200
        }, status=200)
    except Exception as e:
        print(str(e))
        return Response({
            'message': f'注册失败: {str(e)}',
            'code': 400
        }, status=400)


@extend_schema(
    summary="修改用户信息",
    description="返回修改用户信息",
    responses={200: MyUserSerializer}
)
@api_view(['POST'])
def post_userInfo_change(request):
    try:
        user_id = request.data.get('user_id')
        user = myUser.objects.get(id=user_id)

        if 'nickName' in request.data:
            user.nickName = request.data['nickName']
        if 'sex' in request.data:
            user.sex = request.data['sex']
        user.save()
        serializer = MyUserSerializer(user)
        return Response({
            'message': '修改用户信息成功',
            'data': serializer.data,
            'code': 200
        }, status=200)
    except Exception as e:
        print(str(e))
        return Response({
            'message': f'修改用户信息失败: {str(e)}',
            'code': 400
        }, status=400)


@extend_schema(
    summary="修改用户头像",
    description="返回修改用户头像",
    responses={200: MyUserSerializer}
)
@api_view(['POST'])
def post_user_img(request):
    try:
        user_id = request.POST.get('user_id')
        user = myUser.objects.get(id=user_id)
        userImg = request.FILES.get('userImg')

        if not userImg:
            return Response({
                'message': '未上传图片',
                'code': 200
            }, status=200)
        fs = FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT, 'userImg'))
        img_name = fs.save(userImg.name, userImg)
        print(settings.MEDIA_URL + "/userImg/" + img_name)
        user.userImg = "/userImg/" + img_name
        user.save()

        serializer = MyUserSerializer(user)
        return Response({
            'message': '修改用户头像成功',
            'data': "/userImg/" + img_name,
            'code': 200
        }, status=200)
    except Exception as e:
        return Response({
            'message': f'修改用户头像失败: {str(e)}',
            'code': 400
        }, status=400)


@extend_schema(
    summary="获取标签选项",
    description="返回所有可用的标签选项",
    responses={200: {
        'chooseTagTime': dict(VideoTags.TIME_CHOICES),
        'chooseTagType': dict(VideoTags.TYPE_CHOICES),
        'chooseTagLength': dict(VideoTags.LENGTH_CHOICES),
        'showTag': {
            "chooseTagTime": "time_tag",
            "chooseTagType": "type_tag",
            "chooseTagLength": "length_tag"
        }
    }}
)
@api_view(['GET'])
def get_video_tag_options(request):
    # 返回所有可用的标签选项
    return Response({
        'data': {
            'chooseTagTime': dict(VideoTags.TIME_CHOICES),
            'chooseTagType': dict(VideoTags.TYPE_CHOICES),
            'chooseTagLength': dict(VideoTags.LENGTH_CHOICES),
            'chooseTagHot': dict(VideoTags.HOT_CHOICES),
            'chooseTagClass': dict(VideoTags.CLASS_CHOICES),
            'showTag': {
                "chooseTagTime": "time_tag",
                "chooseTagType": "type_tag",
                "chooseTagLength": "length_tag",
                "chooseTagHot": "hot_tag",
                "chooseTagClass": "class_tag"
            }
        },
        'code': 200
    }, status=200)


@extend_schema(
    summary="获取视频列表",
    description="返回所有视频信息",
    responses={200: VideoSerializer}
)
@api_view(['GET'])
def get_video_list(request):
    videos = video.objects.annotate(
        average_score=Round(Avg('score__score'), 1)  # score__score: 第一个score是关联的模型名，第二个是字段名
    ).all()
    serializer = VideoSerializer(videos, many=True)
    if len(serializer.data) == 0:
        return Response({
            'message': '没有视频',
            'data': [],
            'code': 200
        }, status=200)
    return Response({
        'message': '获取视频成功',
        'data': serializer.data,
        'code': 200
    }, status=200)


@extend_schema(
    summary="获取标签视频",
    description="返回标签视频信息",
    responses={200: VideoSerializer}
)
@api_view(['GET'])
def get_tag_videos(request, video_type):
    filter_kwargs = {}
    messages = {
        'hot': '获取热门视频成功',
        'new': '获取最新视频成功',
        'vip': '获取VIP视频成功'
    }

    if video_type in ['hot', 'new']:
        filter_kwargs['hot_tag'] = video_type.upper()
    elif video_type == 'vip':
        filter_kwargs['class_tag'] = 'VIP'

    videos = video.objects.annotate(
        average_score=Round(Avg('score__score'), 1)
    ).filter(**filter_kwargs).order_by('-average_score')[:20]

    serializer = VideoSerializer(videos, many=True)
    return Response({
        'message': messages.get(video_type, '获取视频成功'),
        'data': serializer.data,
        'code': 200
    }, status=200)


@extend_schema(
    summary="获取视频详情",
    description="返回视频详情",
    responses={200: VideoSerializer}
)
@api_view(['POST'])
def post_video_detail(request):
    try:
        video_id = request.data.get('video_id')
        user_id = request.data.get('user_id')
        print(video_id, user_id)
        if not (video_id and user_id):
            return Response({
                'message': '没有传入video_id或user_id',
                'code': 400
            }, status=400)
        theVideo = video.objects.annotate(
            average_score=Round(Avg('score__score'), 1),
            count_score=Count('score__score'),
            collect_is=Subquery(
                collect.objects.filter(
                    user_id=user_id,
                    video_id=OuterRef('id')
                ).values('is_collect')[:1])
        ).get(id=video_id)
        serializer = VideoSerializer(theVideo)
        return Response({
            'message': '获取视频成功',
            'data': serializer.data,
            'code': 200
        }, status=200)
    except Exception as e:
        print(str(e))
        return Response({
            'message': f'获取视频失败: {str(e)}',
            'code': 400
        }, status=400)


@extend_schema(
    summary="获取评论列表",
    description="返回所有评论信息",
    responses={200: CommentSerializer}
)
@api_view(['GET'])
def get_comment(request):
    video_id = request.query_params.get('video_id') or request.data.get('video_id')
    user_id = request.query_params.get('user_id') or request.data.get('user_id')
    if not (video_id or user_id):
        return Response({
            'message': '没有传入video_id或user_id',
            'code': 400
        }, status=400)

    # 基础查询集
    base_query = comment.objects.annotate(
        likes_count=Count('like', filter=Q(like__is_like=True), distinct=True),
        dislikes_count=Count('like', filter=Q(like__is_dislike=True), distinct=True),
        user_score=Subquery(
            score.objects.filter(
                user_id=OuterRef('user_id'),
                video_id=OuterRef('video_id')
            ).values('score')[:1]
        )
    )

    # 根据条件过滤
    if video_id:
        comments = base_query.filter(video_id=video_id).distinct()
    elif user_id:
        comments = base_query.filter(user_id=user_id).distinct()

    # 预加载关联数据
    comments = comments.select_related('user', 'video').prefetch_related('like')

    serializer = CommentSerializer(comments, many=True)

    if not serializer.data:
        return Response({
            'message': '没有评论',
            'data': [],
            'code': 200
        }, status=200)

    return Response({
        'message': '获取评论成功',
        'data': serializer.data,
        'code': 200
    }, status=200)


@extend_schema(
    summary="发布评论",
    description="返回发布评论信息",
    responses={200: CommentSerializer}
)
@api_view(['POST'])
def post_comment(request):
    try:
        video_id = request.data.get('video_id')
        user_id = request.data.get('user_id')
        content = request.data.get('content')
        addComment = comment.objects.create(video_id=video_id, user_id=user_id, content=content)
        serializer = CommentSerializer(addComment)
        return Response({
            'message': '发布评论成功',
            'data': serializer.data,
            'code': 200
        }, status=200)
    except Exception as e:
        print(str(e))
        return Response({
            'message': f'发布评论失败: {str(e)}',
            'code': 400
        }, status=400)


@extend_schema(
    summary="获取点赞列表",
    description="返回所有点赞信息",
    responses={200: LikeSerializer}
)
@api_view(['GET'])
def get_like(request):
    user_id = request.query_params.get('user_id') or request.data.get('user_id')
    comment_id = request.query_params.get('comment_id') or request.data.get('comment_id')
    # 如果传入video_id，则返回该视频的点赞，如果传入user_id，则返回该用户的点赞
    if user_id:
        likes = like.objects.filter(user_id=user_id, is_like=True)
    elif comment_id:
        likes = like.objects.filter(comment_id=comment_id, is_like=True)
    else:
        return Response({
            'message': '没有传入user_id或comment_id',
        }, status=400)
    serializer = LikeSerializer(likes, many=True)
    if len(serializer.data) == 0:
        return Response({
            'message': '没有点赞',
            'data': [],
            'code': 200
        }, status=200)
    return Response({
        'message': '获取点赞成功',
        'data': serializer.data,
        'code': 200
    }, status=200)


@extend_schema(
    summary="修改点赞",
    description="返回修改点赞信息",
    responses={200: LikeSerializer}
)
@api_view(['POST'])
def post_like(request):
    try:
        user_id = request.data.get('user_id')
        comment_id = request.data.get('comment_id')
        isLike = request.data.get('isLike')
        isDislike = request.data.get('isDislike')
        # 查找现有记录
        like_obj = like.objects.filter(user_id=user_id, comment_id=comment_id).first()

        if like_obj:
            # 更新现有记录
            like_obj.is_like = isLike
            like_obj.is_dislike = isDislike
            like_obj.save()
        else:
            # 创建新记录
            like_obj = like.objects.create(
                user_id=user_id,
                comment_id=comment_id,
                is_like=isLike,
                is_dislike=isDislike
            )

        serializer = LikeSerializer(like_obj)  # 注意这里传入单个对象而不是 QuerySet
        return Response({
            'message': '修改点赞成功',
            'data': serializer.data,
            'code': 200
        }, status=200)
    except Exception as e:
        print(str(e))  # 添加错误日志打印
        return Response({
            'message': f'修改点赞失败: {str(e)}',
            'code': 400
        }, status=400)


@extend_schema(
    summary="获取评分列表",
    description="返回所有评分信息",
    responses={200: ScoreSerializer}
)
@api_view(['GET'])
def get_score(request):
    video_id = request.query_params.get('video_id') or request.data.get('video_id')
    user_id = request.query_params.get('user_id') or request.data.get('user_id')
    # 如果传入video_id，则返回该视频的评分，如果传入user_id，则返回该用户的评分
    if video_id:
        scores = score.objects.filter(video_id=video_id)
    elif user_id:
        scores = score.objects.filter(user_id=user_id)
    else:
        return Response({
            'message': '没有传入video_id或user_id',
        }, status=400)
    serializer = ScoreSerializer(scores, many=True)
    if len(serializer.data) == 0:
        return Response({
            'message': '没有评分',
            'data': [],
            'code': 200
        }, status=200)
    return Response({
        'message': '获取评分成功',
        'data': serializer.data,
        'code': 200
    }, status=200)


@extend_schema(
    summary="修改评分",
    description="返回修改评分信息",
    responses={200: ScoreSerializer}
)
@api_view(['POST'])
def post_score(request):
    try:
        user_id = request.data.get('user_id')
        video_id = request.data.get('video_id')
        score_value = request.data.get('score')
        if score_value < 0 or score_value > 10:
            return Response({
                'message': '修改评分失败: 评分范围错误',
                'code': 400
            }, status=400)
        # 查找现有记录
        score_obj = score.objects.filter(user_id=user_id, video_id=video_id).first()

        if score_obj:
            score_obj.score = score_value
            score_obj.save()
        else:
            # 创建新记录
            score_obj = score.objects.create(
                user_id=user_id,
                video_id=video_id,
                score=score_value
            )

        serializer = ScoreSerializer(score_obj)  # 注意这里传入单个对象而不是 QuerySet
        return Response({
            'message': '修改评分成功',
            'data': serializer.data,
            'code': 200
        }, status=200)
    except Exception as e:
        print(str(e))  # 添加错误日志打印
        return Response({
            'message': f'修改评分失败: {str(e)}',
            'code': 400
        }, status=400)


@extend_schema(
    summary="获取用户收藏",
    description="返回收藏信息",
    responses={200: CollectSerializer}
)
@api_view(["GET"])
def get_user_collect(request):
    try:
        user_id = request.query_params.get('user_id') or request.data.get('user_id')
        collects = collect.objects.filter(user_id=user_id).order_by('-created_at')
        serializer = CollectSerializer(collects, many=True)
        return Response({
            'message': '获取收藏成功',
            'data': serializer.data,
            'code': 200
        }, status=200)
    except Exception as e:  # 添加错误日志打印
        return Response({
            'message': f'获取收藏失败: {str(e)}',
            'code': 400
        }, status=400)


@extend_schema(
    summary="修改收藏",
    description="返回修改收藏信息",
    responses={200: CollectSerializer}
)
@api_view(['POST'])
def post_collect(request):
    try:
        user_id = request.data.get('user_id')
        video_id = request.data.get('video_id')
        changeTag = request.data.get('changeTag')
        collect_obj = collect.objects.filter(user_id=user_id, video_id=video_id).first()
        if collect_obj and not changeTag:
            collect_obj.delete()
            return Response({
                'message': '取消收藏成功',
                'code': 200
            }, status=200)
        else:
            collect_obj = collect.objects.create(
                user_id=user_id,
                video_id=video_id,
                is_collect=changeTag
            )
            serializer = CollectSerializer(collect_obj)
            return Response({
                'message': '添加收藏成功',
                'data': serializer.data,
                'code': 200
            }, status=200)
    except Exception as e:
        return Response({
            'message': f'修改收藏失败: {str(e)}',
            'code': 400
        }, status=400)
